-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
kvs: handle non-JSON values in flux kvs get, put, dir #1257
Conversation
just beginning to review, but a thought that comes to mind, are many options in |
Hmm, it does seem like get-treeobj and put-treeobj are obviously the same as get/put with the --treeobj option. I'll see if I can do some of that cleanup here. |
@@ -56,6 +56,16 @@ static void dump_kvs_dir (const flux_kvsdir_t *dir, bool Ropt, bool dopt); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in commit comment, "strong" -> "string"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, my review comment appears to be attached to file and not a commit. This is in commit f93f776
8135869
to
99a1795
Compare
Codecov Report
@@ Coverage Diff @@
## master #1257 +/- ##
==========================================
+ Coverage 77.86% 77.92% +0.06%
==========================================
Files 154 154
Lines 28934 29027 +93
==========================================
+ Hits 22530 22620 +90
- Misses 6404 6407 +3
|
Just rebased on current master, fixed commit comment, and added some commits that move functionality out of
Good suggestion @chu11. All that's left in the test command is the type checking stuff. |
t/t1000-kvs.t
Outdated
flux kvs put $DIR.valref=$(seq -s 1 100) && | ||
flux kvs mkdir $DIR.dirref && | ||
flux kvs link foo $DIR.symlink && | ||
flux kvs get --treeobj $DIR.val && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps | grep "dir"
and equivalents should be added to make sure the right treeobj is being returned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that's a good improvement.
t/t1000-kvs.t
Outdated
test_expect_success 'kvs: empty string value does not cause dir to fail' ' | ||
flux kvs unlink -Rf $DIR && | ||
flux kvs put $DIR.a= && | ||
flux kvs dir $DIR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this test (and the ls one below) also make sure the directory is output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, will fix that.
@garlick awesome. A bunch of the tests can probably be moved from |
just finished skimming. Nothing stands out to me as a problem. Before your rebase, it felt like there were a lack of basic A good test I thought of was to mix treeobj & raw. Off the top of my head:
|
t/t1000-kvs.t
Outdated
flux kvs put $DIR.a.b=goodbye && | ||
flux kvs put --treeobj $DIR.b=$(flux kvs get --treeobj $DIR.a) && | ||
(flux kvs get $DIR.a.a && flux kvs get $DIR.a.b) >snap.expected && | ||
(flux kvs get $DIR.b.a && flux kvs get $DIR.b.b) >snap.actual |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chain-lint needs &&?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
Just pushed some changes to address your comments, except I didn't add any new raw tests or move any tests between the two sharness scripts. I agree the test scripts are a little haphazard in the way they've accreted tests over time and could use a cleanup pass (possibly cleanup is for another time though?) I'll go through the raw tests including the converted ones tomorrow and see if there are any obvious gaps. |
restarted one builder after hang in the cron tests |
agreed, we should cleanup the tests another day. After this PR is done, we can make an issue for it. I'm sure after append support, the tests haphazardness will just be weirder. We may want to split it up amongst even more files instead of just "core" and "extra". |
I didn't entirely understand what was meant here - maybe I am misreading
the first command would encode { tree object val } inside a tree object val, the second would pull it out again. Is nesting those meaningful? On reorganizing - a good start would be to separate the kvs_watch tests out to their own script since they are a bit complicated and are likely to change when watch is reworked. |
@garlick ahh, no nesting intended. I guess I shouldn't have used brackets. First line is to just write a treeobj, second line to read it back and make sure it wrote correctly. I also realize now that the 4th line probably should have been with |
I've pushed some raw tests, mainly exercising the To be clear, --treeobj gives direct access to the RFC 11 object and --raw creates a 'val' object just like --json or no options. I'm still confused by the suggestion - maybe we should chat face to face. |
Problem: flux-kvs put presumes values should be stored as JSON, but the KVS no longer requires this. Add type options to allow the user to choose how values are stored. If no options, value is stored as a NULL terminated string. If --raw, value is stored as with no options, but without a NULL terminator. For --raw mode only, key=- may be used to take read value from stdin. If --json, value is stored as a NULL terminated string if it is valid encoded JSON; otherwise it is first encoded as a JSON string. This mimics the old default behavior of flux-kvs put that is expected by many tests in t1000-kvs.t and t1002-kvs-extra.t. Add --json to flux kvs put where used in various sharness tests. Partial fix to flux-framework#1159.
Problem: flux-get put presumes values should be interpreted as JSON, but the KVS no longer requires this. Add type options mirroring those added to the "put" subcommand to allow the user to choose how values are interpreted. If no options, value is interpreted as a NULL terminated string and written to stdout with a newline. If --raw, value is interpreted as raw data and is written to stdout without any formatting. If --json, value is interpreted as encoded JSON. If the value is an object or array, or any scalar type but string, it is displayed in its encoded form. If the value is a JSON string, quotes are removed, which mimics the old default behavior of flux-kvs get expected by many sharness tests. Add --json to flux kvs get where used in various sharness tests. Fixes flux-framework#1159
908824a
to
35700cb
Compare
Squashed. |
src/cmd/flux-kvs.c
Outdated
char *val, *kv, *p; | ||
bool overflow = false; | ||
|
||
assert (maxcol == 0 || maxcol > 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just realized, I don't think there's a check for a reasonable maxcol in callers of this function. Should a check be added somewhere? Or perhaps there should just be a generic "can't output with such small width" kind of error message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you're right.
doc/man1/flux-kvs.adoc
Outdated
|
||
*put* 'key=value' ['key=value...']:: | ||
*put* [-j|-r] 'key=value' ['key=value...']:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need -t and -n
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could swear I already did that one. Thanks!
doc/man1/flux-kvs.adoc
Outdated
If '-j', it is first encoded as JSON, then stored as a NULL-terminated string. | ||
If '-r', it is stored as raw data with no termination. For raw mode only, | ||
a value of "-" indicates that the value should be read from standard input. | ||
If '-t', value is stored as a RFC 11 object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and description of -n.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right! Adding that.
other than those nits above, I think things look good. Did you want to squash? |
ee42344
to
14b3581
Compare
Thanks! Re-squashed. |
Problem: the KVS allows non-JSON values to be stored, but flux kvs dir -R exits with an error if it encounters one. For each value, if it decodes as JSON, format it like before. But if it doesn't, print it directly instead of exiting. If the output is a terminal, truncate long values so they fit within the terminal width (reusing logic from the ls subcommand). Also truncate values where they contain unprintable characters or newlines. Indicate truncated values by appending "...". Fixes flux-framework#1158
If --treeobj is specified, display RFC 11 object directly instead of parsing it. Allow directories to be listed too.
If --treeobj is specified store value argument as a RFC 11 object. Example, assign snapshot of 'lwj' to 'lwj.snapshot': flux kvs put --treeobj \ lwj.snapshot=$(flux kvs get --treeobj lwj)
Problem: flux kvs get (no options) segfaults if key refers to a zero-length value. If value is zero-length, print nothing instead of handing a NULL pointer to printf.
Problem: if value is zero-length, get --json displays "null", but it should be an error like any other value that doesn't decode as valid JSON, for example the empty string. output_key_json_string() is doing double duty with the watch subcommand, which still treats a NULL value as a non-existent key. Don't pass a NULL value to that function; instead, treat it as an error beforehand.
Add flux-kvs get/readlink/dir --at REF option that allows a lookup to start with a snapshot reference.
Add put --no-merge flag which ensures that flux_commit() is called with the FLUX_KVS_NO_MERGE flag.
Ensure that flux kvs get --treeobj and flux kvs put --treeobj work as designed.
Ensure that an empty string value (just a NULL) can be created and parsed where appropriate.
Replace "t/kvs/basic get-treeobj" with "flux kvs get --treeobj" and "t/kvs/basic put-treeobj" with "flux kvs put --treeobj" in sharness test. Drop get-treeobj, put-treeobj subcommands from test program.
Replace "t/kvs/basic dirsize" with "flux kvs ls -1 | wc -l" and drop the dirsize subcommand from the test program.
Replace "t/kvs/basic getat" with "flux kvs get --at", "t/kvs/basic readlinkat" with "flux kvs readlink --at", and "t/kvs/basic dirat" with "flux kvs dir --at". Drop getat, readlinkat, dirat subcommands from the test program.
Replace "t/kvs/basic put-no-merge" with "flux kvs put --no-merge --json" and drop the put-no-merge subcommand from the test program.
Replace "t/kvs/basic copy-fromkvs" with "flux kvs get --raw" and "t/kvs/basic copy-tokvs key -" with "flux kvs put --raw key=-", and drop copy-fromkvs/copy-tokvs subcommands from test program.
Drop this test kvs: zero size raw value can be stored and retrieved It is basically the same as this one in t1000-kvs.t: kvs: zero-length value handled by put/get --raw
Describe get/put [--json|--raw|--treeobj] options. Describe get/dir/readlink [--at treeobj] option. Describe dir truncation to fit output window and [-w COL] option.
everything, lgtm! |
Problem: The "module-load: no jobs are lost" subtest of sharness t1004-module-load.t is failing. The test is comparing "status" (with quotes) to status (without quotes). The value in the KVS is a JSON string, but flux-framework/flux-core#1257 changed flux-kvs so that it displays raw values by default, in this case the encoded JSON string with the quotes. Add -j to the flux kvs get command in the test, to get the old behavior.
This PR updates the
flux kvs
command to handle non-JSON values. These deficiencies were discussed in #1158 and #1159.A summary of the changes proposed here are:
flux kvs dir
displays non-JSON valuesflux kvs dir
truncates output to fit terminal width, controlled with--width=COLS
flux kvs put
andflux kvs get
now accept the--raw
,--json
, and--treeobj
options to allow greater control over how values are stored and interpreted.As a reminder the KVS just stores raw values now, imposing no structure. We have convenience functions for get/put of strings (NULL terminated), and JSON (encoded as strings). The get/put subcommands now default to storing strings, as opposed to JSON-encoded strings. The
--json
option was added to emulate the past behavior. The--raw
options was added to allow non-NULL terminated byte sequences to be stored and retrieved. The--treeobj
option was added so that snapshots could be manipulated and metadata could be examined conveniently.Man pages updated and sharness tests added.